package ink.ykb.demo.user.service;

import java.util.Date;

import org.apache.commons.lang3.StringUtils;
import org.beetl.sql.core.engine.PageQuery;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.cache.annotation.Caching;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import ink.ykb.demo.config.CodeConstant;
import ink.ykb.demo.config.MessageUtil;
import ink.ykb.demo.config.ServiceException;
import ink.ykb.demo.permission.enums.Status;
import ink.ykb.demo.user.dao.UserInfoDao;
import ink.ykb.demo.user.entity.UserInfo;
import ink.ykb.demo.user.service.dto.UserInfoPage;
import ink.ykb.demo.util.PageInfo;
import ink.ykb.demo.util.PwdUtil;

@Service
public class UserInfoServiceImpl implements UserInfoService {

	@Autowired
	private UserInfoDao userInfoDao;
	@Autowired
	private MessageUtil messageUtil;

	@Transactional
	@Override
	public void add(UserInfo userInfo) {
		if (userInfo == null) {
			throw new ServiceException(CodeConstant.PARAMS_EMPTY, messageUtil.getMsg(CodeConstant.PARAMS_EMPTY));
		}
		if (StringUtils.isBlank(userInfo.getUserName())) {
			throw new ServiceException(CodeConstant.PARAMS_EMPTY, messageUtil.getMsg(CodeConstant.PARAMS_EMPTY));
		}
		if (StringUtils.isBlank(userInfo.getPassword())) {
			throw new ServiceException(CodeConstant.PARAMS_EMPTY, messageUtil.getMsg(CodeConstant.PARAMS_EMPTY));
		}

		
		UserInfo dbUserInfo = userInfoDao.getUserInfoAndLock(userInfo.getUserName());
		if (dbUserInfo != null) {
			throw new ServiceException(CodeConstant.MUS_108, messageUtil.getMsg(CodeConstant.MUS_108));
		}

		userInfo.setPassword(PwdUtil.createHash(userInfo.getPassword()));
		userInfo.setCreateTime(new Date());
		userInfo.setStatus(Status.YES.getValue());
		userInfoDao.insert(userInfo);

	}

	@Caching(evict = { @CacheEvict(cacheNames = { "userInfo" }, key = "#userInfo.id") })
	@Transactional
	@Override
	public void update(UserInfo userInfo) {
		if (userInfo == null) {
			throw new ServiceException(CodeConstant.PARAMS_EMPTY, messageUtil.getMsg(CodeConstant.PARAMS_EMPTY));
		}
		if (userInfo.getId() == null) {
			throw new ServiceException(CodeConstant.PARAMS_EMPTY, messageUtil.getMsg(CodeConstant.PARAMS_EMPTY));
		}
		if (StringUtils.isBlank(userInfo.getUserName())) {
			throw new ServiceException(CodeConstant.PARAMS_EMPTY, messageUtil.getMsg(CodeConstant.PARAMS_EMPTY));
		}

		// 判断namecode是否重复
		UserInfo dbNameUserInfo = userInfoDao.getUserInfoAndLock(userInfo.getUserName());
		if (dbNameUserInfo != null && !dbNameUserInfo.getId().equals(userInfo.getId())) {
			throw new ServiceException(CodeConstant.MUS_108, messageUtil.getMsg(CodeConstant.MUS_108));
		}

		UserInfo dbUserInfo = userInfoDao.getUserInfoById(userInfo.getId());
		if (dbUserInfo == null) {
			throw new ServiceException(CodeConstant.USER_EMPTY, messageUtil.getMsg(CodeConstant.USER_EMPTY));
		}

		if(StringUtils.isNotBlank(userInfo.getPassword())) {
			dbUserInfo.setPassword(PwdUtil.createHash(userInfo.getPassword()));
		}
		
		dbUserInfo.setUserName(userInfo.getUserName());

		userInfoDao.updateById(dbUserInfo);
	}

	@Caching(evict = { @CacheEvict(cacheNames = { "userInfo" }, key = "#userId") })
	@Transactional
	@Override
	public void delete(Long userId) {
		UserInfo dbUserInfo = userInfoDao.getUserInfoById(userId);
		if (dbUserInfo == null) {
			throw new ServiceException(CodeConstant.USER_EMPTY, messageUtil.getMsg(CodeConstant.USER_EMPTY));
		}

		dbUserInfo.setStatus(Status.NO.getValue());
		userInfoDao.updateById(dbUserInfo);

	}

	@Cacheable(cacheNames = "userInfo", key = "#userId")
	@Override
	public UserInfo getUserInfo(Long userId) {
		return userInfoDao.getUserInfoById(userId);
	}

	@Override
	public UserInfo getUserInfo(String userName) {
		return userInfoDao.getUserInfo(userName);
	}

	@Override
	public PageInfo<UserInfo> getUserInfoPage(UserInfoPage userInfoPage) {
		if(userInfoPage == null) {
			userInfoPage = new UserInfoPage(20, 1);
		}
		if(userInfoPage.getPageSize() == null) {
			userInfoPage.setPageSize(20);
		}
		if(userInfoPage.getPageNumber() == null) {
			userInfoPage.setPageNumber(1);
		}
		PageQuery<UserInfo> query = new PageQuery<>();
		query.setPageNumber(userInfoPage.getPageNumber());
		query.setPageSize(userInfoPage.getPageSize());
		query.setOrderBy(userInfoPage.getOrderBy());
		query.setParas(userInfoPage);
		
		PageQuery<UserInfo> pageQuery = userInfoDao.getPage(query);
		
		PageInfo<UserInfo> page = new PageInfo<>(userInfoPage.getPageSize(), userInfoPage.getPageNumber());
		page.setList(pageQuery.getList());
		page.setTotalCount(pageQuery.getTotalRow());
		page.setTotalPages(pageQuery.getTotalPage());
		
		return page;
	}

}
